package services

import (
	"bytes"
	"context"
	"crypto/tls"
	"encoding/json"
	"errors"
	"fmt"
	"github.com/sirupsen/logrus"
	"io"
	"net/http"
	"net/url"
	"strconv"
	"strings"
	"time"
	"wecom_rebot/common"
	"wecom_rebot/core"
	"wecom_rebot/models"
)

var adOpenAccountLogger *logrus.Logger

// InitAdAccountOpenLogger 移除 init() 函数，改为显式初始化函数
func InitAdAccountOpenLogger() {
	// 确保在 common 初始化后调用
	adOpenAccountLogger = core.InitLogger(common.LogsErrorMap[11])
}

type analyzeAdOpenAccountContentResult struct {
	AccountName    string
	WithoutID      int64
	Contact        string
	SelectIndustry string
}

type SearchWithoutCustomerResponse struct {
	CustomerID      int64  `json:"customerId"`
	CustomerName    string `json:"customerName"`
	IndustryId      int64  `json:"industryId"`
	SmallIndustryId int64  `json:"smallIndustryId"`
	FirstIndustry   string `json:"firstIndustry"`
	SmallIndustry   string `json:"smallIndustry"`
}

type SearchWithoutResponse struct {
	Code int                             `json:"code"`
	Msg  string                          `json:"msg"`
	Data []SearchWithoutCustomerResponse `json:"data"`
}

// ContactResponse 获取联系人信息
type ContactResponse struct {
	Code int    `json:"code"`
	Msg  string `json:"msg"`
	Data struct {
		Contacts             []Contact              `json:"contacts"`
		QualificationInfoVos []QualificationInfoVos `json:"qualificationInfoVos"`
	} `json:"data"`
}

// Contact 联系人身份证信息
type Contact struct {
	ContactName     string `json:"contactName"`
	IDCardNo        string `json:"idCardNo"`
	Mobile          string `json:"mobile"`
	Email           string `json:"email"`
	MaskContactName string `json:"maskContactName"`
	ContactID       int64  `json:"contactId"`
	ContactType     string `json:"contactType"`
	DefaultContact  bool   `json:"defaultContact"`
	ContactStatus   int    `json:"contactStatus"`
	MaskIdCardNo    string `json:"maskIdCardNo"`
	MaskMobile      string `json:"maskMobile"`
	MaskEmail       string `json:"maskEmail"`
}

// QualificationInfoVos 地址信息
type QualificationInfoVos struct {
	QualificationType   int    `json:"qualificationType"`
	QualificationCode   string `json:"qualificationCode"`
	LicenseCountryId    string `json:"licenseCountryId"`
	LicenseCountryName  string `json:"licenseCountryName"`
	LicenseProvinceName string `json:"licenseProvinceName"`
	LicenseCityName     string `json:"licenseCityName"`
}

// SubmitData 主提交结构体
type SubmitData struct {
	// 基础信息
	AgentID string `json:"agentId"` // agentId 固定值
	Name    string `json:"name"`    // 账户名称+后缀
	Company string `json:"company"` // 原始账户名称

	// 固定字段
	SystemOrigin string `json:"systemOrigin"` // 固定值0

	// 营业执照信息
	LicenseType int    `json:"license_type"` // 营业执照类型
	LicenseNo   string `json:"license_no"`   // 营业执照编号

	// 联系人信息
	ContactMobile string `json:"contactMobile"` // 联系人手机号
	OwnerType     string `json:"ownerType"`     // 固定值SELF
	AccountCate   int    `json:"accountCate"`   // 固定值0

	// 行业信息
	FirstIndustryCode  int64 `json:"first_industry_code"`  // 一级行业代码
	SecondIndustryCode int64 `json:"second_industry_code"` // 二级行业代码

	// 地址信息
	ManagementAddress ManagementAddress `json:"managementAddress"` // 管理地址

	// 营业执照详细地址
	LicenseCountry     string `json:"license_country"`      // 国家代码
	LicenseCountryName string `json:"license_country_name"` // 国家名称
	LicenseProvince    string `json:"license_province"`     // 省份名称
	LicenseCity        string `json:"license_city"`         // 城市名称

	// 提交信息
	URLSource string `json:"urlSource"` // 空字符串
	Submit    bool   `json:"submit"`    // 提交标志
}

// ManagementAddress 地址管理结构体
type ManagementAddress struct {
	BillingAddress Address `json:"billing_address"` // 账单地址
	ContactAddress Address `json:"contact_address"` // 联系地址
	OfficeAddress  Address `json:"office_address"`  // 办公地址
}

// Address 地址结构体
type Address struct {
	NationCode string `json:"nation_code"` // 国家代码
}

// CreateAccountResponse 创建账户
type CreateAccountResponse struct {
	Code int    `json:"code"`
	Msg  string `json:"msg"`
	Data struct {
		ErrorState int    `json:"errorState"`
		CustomerId string `json:"customerId"`
		AdvId      string `json:"advId"`
		AdvName    string `json:"advName"`
		ErrMsg     string `json:"msg"` // 区分顶层Msg和data.Msg
	} `json:"data"`
}

type HugeAdOpenAccountService struct{}

func (s *HugeAdOpenAccountService) Handle(msgId int, subjectName, roomId string, content []string, jobId uint64) error {
	var msg = &models.Msg{}

	fmt.Println("adOpenAccountLogger", "原始结构Id：", msgId)
	// 获取数据
	err := common.DB.Where("id = ?", msgId).First(&msg).Error
	if err != nil {
		adOpenAccountLogger.Error("巨量AD获取数据失败", common.LogsErrorMap[2], msgId, err)
		return err
	}

	adOpenAccountLogger.Info("adOpenAccountLogger", "原始结构：", content)

	// 处理需要的数据结构
	result, err := s.analyzeContent(content)
	if err != nil {
		adOpenAccountLogger.Error(err)
		return err
	}

	// 移除功能行
	msg.Content = RemoveTitle(msg)
	fmt.Println("adOpenAccountLogger", result, "移除后的结构：", msg, "广告主信息：", content)

	rdb := core.InitRedis(13)
	ctx := context.Background()

	cookies, err := rdb.Get(ctx, "laravel_database_oead_adv_cookies").Result()

	fmt.Println("adOpenAccountLogger", "Cookies:", cookies)

	// 查询任务
	var job models.Job
	if err = common.DB.Where("id = ?", jobId).First(&job).Error; err != nil {
		adOpenAccountLogger.Error("查询完整任务记录", common.LogsErrorMap[2], jobId, err)
		return err
	}

	// 第一步 获取证件号码
	documentList, err := s.getDocumentNumber("1629698414782477", result.AccountName, cookies)
	if err != nil {
		adOpenAccountLogger.Warnf("获取证件号码失败: %v", err)
		return errors.New("媒体提示4：" + err.Error())
	}

	var customerValue SearchWithoutCustomerResponse
	// 传入直客信息ID
	if result.WithoutID != 0 {
		// 查询直客信息
		searchWitch, err := s.getSearchWithout(result.AccountName, documentList.Data.CompanyList[0].LicenseNo, cookies, documentList.Data.CompanyList[0].LicenseType)
		if err != nil {
			adOpenAccountLogger.Error("获取直客信息失败", common.LogsErrorMap[2], result.AccountName, err)
			return errors.New("获取直客信息失败：" + err.Error())
		}

		// 不存在直客
		customerResponse, ok := findMatchCustomerId(searchWitch.Data, result.WithoutID)
		if !ok {
			errE := BendiSendText(msg.Content+"\n-----------------------------------\n直客ID不匹配", msg.RoomID, msg.Sender)
			if errE != nil {
				return errE
			}
		}
		customerValue.IndustryId = customerResponse.IndustryId
		customerValue.SmallIndustryId = customerResponse.SmallIndustryId
		adOpenAccountLogger.Info("如果存在直客的情况下的参数：", searchWitch.Data)
		adOpenAccountLogger.Info("用户传入的参数：", result.WithoutID)
	} else {
		// 未传入直客信息ID
		var industry models.OeSelectIndustry
		err = common.DBDk.Where("account_name = ?", result.AccountName).Take(&industry).Error
		if err != nil {
			encodedName := url.QueryEscape(result.AccountName)
			// 拼接完整的 URL
			sprintfUrl := fmt.Sprintf("https://web.disbursements.ecoremedia.net/#/other/account_industry?account_name=%s&media=oead&account_id=", encodedName)
			err := BendiSendText(msg.Content+"\n-----------------------------------\n直客未存在情况，请点击链接手动设置行业"+"\n"+sprintfUrl, msg.RoomID, msg.Sender)
			if err != nil {
				return err
			}
		}
		customerValue.IndustryId = industry.FirstIndustryCode
		customerValue.SmallIndustryId = industry.SecondIndustryCode
	}

	contacts, qualificationInfos, err := s.getContactsPerson(result.AccountName, cookies)
	if err != nil {
		adOpenAccountLogger.Error("获取联系人信息失败", common.LogsErrorMap[2], result.AccountName, err)
		errE := BendiSendText(msg.Content+"\n-----------------------------------\n获取联系人信息失败："+err.Error(), msg.RoomID, msg.Sender)
		if errE != nil {
			return errE
		}
		return err
	}

	adOpenAccountLogger.Info("联系人信息：", contacts)
	adOpenAccountLogger.Info("资质信息：", qualificationInfos)

	// 查找匹配联系人
	contact, matched := findMatch(contacts, result.Contact)
	if !matched {
		adOpenAccountLogger.Warnf("联系人不匹配: %s", result.Contact)
		return fmt.Errorf("联系人不匹配: %s", result.Contact)
	}

	// 使用匹配的联系人进行后续处理
	adOpenAccountLogger.Info("找到联系人：", contact)

	createData := s.buildSubmitData(result.AccountName, qualificationInfos[0], contact.Mobile, customerValue)

	createResponse, err := s.createAccount(createData, cookies)
	if err != nil {
		adOpenAccountLogger.Errorf("创建账户失败: %v", err)
		return fmt.Errorf("创建账户失败: %v", err)
	}

	err = BendiSendText(fmt.Sprintf("%s\n-----------------------------------\n开户成功：%s", msg.Content, createResponse.Data.AdvName), msg.RoomID, msg.Sender)
	if err != nil {
		adOpenAccountLogger.Errorf("发送开户成功消息失败: %v", err)
		return err
	}

	// 将基础信息插入表中，方便后面定时任务同步到OA中
	createAccountRecord := &models.NewOpenAccountRecord{
		SubAccountName:  result.AccountName,
		AccountID:       createResponse.Data.AdvId,
		Type:            2,
		Status:          1,
		OeWithoutID:     result.WithoutID,
		OeContactPerson: result.Contact,
	}

	err = common.DB.Create(&createAccountRecord).Error
	if err != nil {
		adOpenAccountLogger.Error("创建账户记录失败", err)
		return err
	}

	return nil
}

// 获取证件号码
func (s *HugeAdOpenAccountService) getDocumentNumber(agentId, companyName string, cookies string) (*getDocument, error) {
	documentUrl := fmt.Sprintf("https://agent.oceanengine.com/agent/adv-create/profile/company-name-check/v2?agentId=%s&companyName=%s", agentId, companyName)

	var result getDocument
	err := s.SendCurlRequest(documentUrl, nil, cookies, "GET", "", &result)
	if err != nil {
		return nil, err
	}

	adOpenAccountLogger.Info("获取证件号码：", result)

	if result.Code != 0 {
		adOpenAccountLogger.Error("获取证件号码失败", result)
		return nil, fmt.Errorf("获取证件号码失败: %s", result.Msg)
	}

	return &result, nil
}

// 创建账户
func (s *HugeAdOpenAccountService) createAccount(data interface{}, oeAdCookies string) (*CreateAccountResponse, error) {
	u := "https://agent.oceanengine.com/agent/adv-create/profile/create-adv"

	// 使用已有的 SendCurlRequest 方法发送请求
	var response CreateAccountResponse
	err := s.SendCurlRequest(u, data, oeAdCookies, "POST", "", &response)
	if err != nil {
		adOpenAccountLogger.Errorf("创建账户失败: %v", err)
		return nil, fmt.Errorf("发送请求失败: %w", err)
	}

	// 记录原始响应
	adOpenAccountLogger.Infof("创建账户原始响应: %+v", response)

	// 处理响应
	if response.Code != 0 {
		adOpenAccountLogger.Warnf("接口返回错误: %s", response.Msg)
		return &response, fmt.Errorf("接口错误: %s", response.Msg)
	}

	if response.Data.ErrorState != 0 {
		adOpenAccountLogger.Warnf("业务逻辑错误: %s", response.Data.ErrMsg)
		return &response, fmt.Errorf("业务错误: %s", response.Data.ErrMsg)
	}

	adOpenAccountLogger.Infof("账户创建成功: %s", response.Data.ErrMsg)
	return &response, nil
}

// 构造提交数据
func (s *HugeAdOpenAccountService) buildSubmitData(accountName string, qualificationInfo QualificationInfoVos, mobile string, customerValue SearchWithoutCustomerResponse) *SubmitData {
	return &SubmitData{
		// 基础信息
		AgentID: "1629698414782477",
		Name:    accountName + "-yx",
		Company: accountName,

		// 固定字段
		SystemOrigin: "0",

		// 营业执照信息
		LicenseType: qualificationInfo.QualificationType,
		LicenseNo:   qualificationInfo.QualificationCode,

		// 联系人信息
		ContactMobile: mobile,
		OwnerType:     "SELF",
		AccountCate:   0,

		// 行业信息
		FirstIndustryCode:  customerValue.IndustryId,
		SecondIndustryCode: customerValue.SmallIndustryId,

		// 地址信息
		ManagementAddress: ManagementAddress{
			BillingAddress: Address{
				NationCode: qualificationInfo.LicenseCountryId,
			},
			ContactAddress: Address{
				NationCode: qualificationInfo.LicenseCountryId,
			},
			OfficeAddress: Address{
				NationCode: qualificationInfo.LicenseCountryId,
			},
		},

		// 营业执照详细地址
		LicenseCountry:     qualificationInfo.LicenseCountryId,
		LicenseCountryName: qualificationInfo.LicenseCountryName,
		LicenseProvince:    qualificationInfo.LicenseProvinceName,
		LicenseCity:        qualificationInfo.LicenseCityName,

		// 提交信息
		URLSource: "",
		Submit:    true,
	}
}

// 在 HugeAdCopyAccountService 中添加
func (s *HugeAdOpenAccountService) getContactsPerson(companyName, cookies string) ([]Contact, []QualificationInfoVos, error) {
	sprintfUrl := fmt.Sprintf("https://agent.oceanengine.com/agent/adv-create/profile/query-qualification-contact?agentId=1629698414782477&companyName=%s", companyName)

	var response ContactResponse
	err := s.SendCurlRequest(sprintfUrl, nil, cookies, "GET", "", &response)
	if err != nil {
		adOpenAccountLogger.Errorf("获取联系人信息失败: %v", err)
		return nil, nil, err
	}

	if response.Code != 0 {
		adOpenAccountLogger.Warnf("接口返回错误: %s", response.Msg)
		return nil, nil, fmt.Errorf("接口错误: %s", response.Msg)
	}

	if len(response.Data.Contacts) == 0 {
		adOpenAccountLogger.Warn("联系人信息为空")
		return nil, nil, fmt.Errorf("未找到联系人信息")
	}

	return response.Data.Contacts, response.Data.QualificationInfoVos, nil
}

// getSearchWithout 获取直客信息
func (s *HugeAdOpenAccountService) getSearchWithout(accountName, licenseNo, oeAdCookies string, licenseType int) (*SearchWithoutResponse, error) {
	sprintfUrl := fmt.Sprintf("https://agent.oceanengine.com/agent/adv-create/customer/query/?customerName=%s&isQianchuan=false&licenseNo=%s&licenseType=%d", accountName, licenseNo, licenseType)

	var response SearchWithoutResponse
	err := s.SendCurlRequest(sprintfUrl, nil, oeAdCookies, "GET", "", &response)
	if err != nil {
		adOpenAccountLogger.Errorf("获取直客信息失败: %v", err)
		return nil, err
	}

	// 记录完整响应
	adOpenAccountLogger.Infof("getSearchWithout获取直客完整信息: %+v", response)

	// 检查返回码不为0的情况
	if response.Code != 0 {
		adOpenAccountLogger.Warnf("getSearchWithout获取直客信息失败: %s", response.Msg)
		return nil, fmt.Errorf("接口返回错误: %s", response.Msg)
	}

	// 检查data为空的情况
	if len(response.Data) == 0 {
		adOpenAccountLogger.Warnf("getSearchWithout未找到对应的授权信息: %s", response.Msg)
		return nil, fmt.Errorf("未找到直客信息: %s", response.Msg)
	}

	return &response, nil
}

// SendCurlRequest 发送HTTP请求
func (s *HugeAdOpenAccountService) SendCurlRequest(url string, postData interface{}, xhsCookies string, method string, oeCsrfToken string, result interface{}) error {
	// 创建请求上下文
	ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
	defer cancel()

	// 序列化POST数据
	var bodyReader io.Reader
	if postData != nil {
		jsonData, err := json.Marshal(postData)
		if err != nil {
			return fmt.Errorf("JSON序列化失败: %v", err)
		}
		bodyReader = bytes.NewBuffer(jsonData)
	}

	// 创建请求
	req, err := http.NewRequestWithContext(ctx, method, url, bodyReader)
	if err != nil {
		return fmt.Errorf("创建请求失败: %v", err)
	}

	// 设置请求头
	req.Header.Set("Content-Type", "application/json;charset=UTF-8")
	req.Header.Set("Cookie", xhsCookies)
	if oeCsrfToken != "" {
		req.Header.Set("Cg-Csrf-Token", oeCsrfToken)
	}

	// 创建自定义客户端
	client := &http.Client{
		Transport: &http.Transport{
			TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
		},
	}

	// 发送请求
	resp, err := client.Do(req)
	if err != nil {
		return fmt.Errorf("请求失败: %v", err)
	}
	defer resp.Body.Close()

	// 读取响应体
	respBody, err := io.ReadAll(resp.Body)
	if err != nil {
		return fmt.Errorf("读取响应失败: %v", err)
	}

	adOpenAccountLogger.Info("获取后得参数格式：", string(respBody))

	if result != nil {
		if err := json.Unmarshal(respBody, &result); err != nil {
			return fmt.Errorf("JSON解析失败: %v", err)
		}
	}
	return nil
}

// analyzeContent 解析内容为广告主信息数组
func (s *HugeAdOpenAccountService) analyzeContent(content []string) (*analyzeAdOpenAccountContentResult, error) {
	// 初始化结果变量
	var accountName string
	var withoutId int
	var contact string
	var selectIndustry string

	// 遍历内容行
	for _, line := range content {
		// 账户名称
		if strings.HasPrefix(line, "账户名称:") {
			accountName = strings.TrimSpace(strings.TrimPrefix(line, "账户名称:"))
		}
		// 直客ID
		if strings.HasPrefix(line, "直客ID:") {
			strValue := strings.TrimSpace(strings.TrimPrefix(line, "直客ID:"))
			if strValue != "" {
				var err error
				withoutId, err = strconv.Atoi(strValue)
				if err != nil {
					adOpenAccountLogger.Errorf("直客ID转换失败: %v", err)
					return nil, fmt.Errorf("直客ID格式错误: %w", err)
				}
			}
		}
		// 联系人姓名
		if strings.HasPrefix(line, "联系人姓名:") {
			contact = strings.TrimSpace(strings.TrimPrefix(line, "联系人姓名:"))
		}
		// 手动选择行业
		if strings.HasPrefix(line, "手动选择行业:") {
			selectIndustry = strings.TrimSpace(strings.TrimPrefix(line, "手动选择行业:"))
		}
	}
	if accountName == "" {
		adOpenAccountLogger.Warn("未解析到账户名称")
		return nil, errors.New("解析参数失败: 缺少账户名称")
	}

	if contact == "" {
		adOpenAccountLogger.Warn("未解析到contact")
		return nil, errors.New("解析参数失败: 缺少contact")
	}

	return &analyzeAdOpenAccountContentResult{
		AccountName:    accountName,
		WithoutID:      int64(withoutId),
		Contact:        contact,
		SelectIndustry: selectIndustry,
	}, nil
}

func findMatch(contacts []Contact, targetName string) (*Contact, bool) {
	for _, contact := range contacts {
		if contact.ContactName == targetName {
			return &contact, true
		}
	}
	return nil, false
}

func findMatchCustomerId(customers []SearchWithoutCustomerResponse, customerId int64) (*SearchWithoutCustomerResponse, bool) {
	for _, customer := range customers {
		if customer.CustomerID == customerId {
			return &SearchWithoutCustomerResponse{
				CustomerID:      customer.CustomerID,
				IndustryId:      customer.IndustryId,
				SmallIndustryId: customer.SmallIndustryId,
			}, true
		}
	}
	return nil, false
}
